package com.jack.xiaoer.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.jack.xiaoer.constant.MyConstant;
import com.jack.xiaoer.constant.OrderStateEnum;
import com.jack.xiaoer.constant.PayTypeEnum;
import com.jack.xiaoer.dao.CartMapper;
import com.jack.xiaoer.dao.OrderDetailMapper;
import com.jack.xiaoer.dao.OrderMapper;
import com.jack.xiaoer.dto.CartDTO;
import com.jack.xiaoer.dto.OrderDTO;
import com.jack.xiaoer.dto.OrderDetailDTO;
import com.jack.xiaoer.entity.Cart;
import com.jack.xiaoer.entity.Order;
import com.jack.xiaoer.entity.OrderDetail;
import com.jack.xiaoer.service.OrderService;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import java.util.Optional;

/**
 * Created by Jackaroo Zhang on 2018/12/19.
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Override
    public Order create(Optional<OrderDTO> orderDTOOptional) {
        if (!orderDTOOptional.isPresent()) return null;
        final OrderDTO orderDTO = orderDTOOptional.get();

        // 查询用户购物车中已选定的条目
        QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shop_id", orderDTO.getShopId());
        queryWrapper.eq("user_id", orderDTO.getUserId());
        queryWrapper.eq("checked", MyConstant.CHECKED);
        queryWrapper.eq("deleted", MyConstant.UNDELETED);
        List<Cart> carts = cartMapper.selectList(queryWrapper);

        if (carts.isEmpty()) {
            return null;
        }

        final Cart shopInCart = carts.get(0);

        // 构建订单基本信息
        Order order = new Order();
        order.setOrderCode(generateOrderCode(shopInCart.getShopId()));
        order.setShopId(shopInCart.getShopId());
        order.setShopName(shopInCart.getShopName());
        order.setUserId(shopInCart.getUserId());
        order.setNote(orderDTO.getNote());
        order.setPayType(PayTypeEnum.DEFAULT);
        order.setExpectedTime(orderDTO.getExpectedTime());
        order.setState(OrderStateEnum.NO_PAY.getCode());
        order.setGmtCreate(Instant.now());
        order.setGmtModified(Instant.now());

        // 将订单基本信息插入数据库
        int row = orderMapper.insert(order);
        if (row > 0) {
            BigDecimal totalPrice = new BigDecimal(0);
            BigDecimal settlePrice = new BigDecimal(0);
            // 创建并插入订单子项数据
            for (Cart cart : carts) {
                OrderDetail orderDetail = new OrderDetail();
                orderDetail.setOrderId(order.getId());
                orderDetail.setProductId(cart.getProductId());
                orderDetail.setProductCount(cart.getProductCount());
                orderDetail.setProductName(cart.getProductName());
                orderDetail.setProductPrice(cart.getProductPrice());

                BigDecimal odTotalPrice = cart.getProductPrice().multiply(new BigDecimal(cart.getProductCount()));
                BigDecimal odSettlePrice = cart.getProductPrice().multiply(new BigDecimal(cart.getProductCount()));

                totalPrice = totalPrice.add(odTotalPrice);
                settlePrice = settlePrice.add(odSettlePrice);

                orderDetail.setTotalPrice(odTotalPrice.setScale(2, BigDecimal.ROUND_DOWN));
                orderDetail.setSettlePrice(odSettlePrice.setScale(2, BigDecimal.ROUND_DOWN));
                orderDetail.setState(OrderStateEnum.NO_PAY.getCode());
                orderDetail.setGmtCreate(Instant.now());
                orderDetail.setGmtModified(Instant.now());

                int orderDetailRow = orderDetailMapper.insert(orderDetail);
                if (orderDetailRow < 1) {
                    // 一个子项插入失败，需要将之前订单基本信息条目删除
                    int orderRow = orderMapper.deleteById(order.getId());
                    return null;
                }
            }

            // 全部子项插入成功，更新订单基本信息
            order.setTotalPrice(totalPrice.setScale(2, BigDecimal.ROUND_DOWN));
            order.setSettlePrice(settlePrice.setScale(2, BigDecimal.ROUND_DOWN));
            int updatedRow = orderMapper.updateById(order);

            if (updatedRow > 0) {
                // 删除购物车中条目
                List<Long> deletedIds = Lists.newArrayList();
                carts.stream().forEach(cart -> {
                    deletedIds.add(cart.getId());
                });
                cartMapper.deleteBatchIds(deletedIds);
            }

            return order;
        }

        return null;
    }

    @Override
    public Order update(Optional<Order> orderOptional) {
        if (!orderOptional.isPresent()) {
            return null;
        }

        final Order order = orderOptional.get();
        if (order.getId() == null) {
            return null;
        }
        int row = orderMapper.updateById(order);
        if (row < 1) {
            return null;
        }
        Order updatedOrder = orderMapper.selectById(order.getId());

        return updatedOrder;
    }

    @Override
    public OrderDetailDTO getOrderDetail(Long orderId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            return null;
        }

        QueryWrapper<OrderDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id", order.getId());
        List<OrderDetail> orderDetails = orderDetailMapper.selectList(queryWrapper);

        OrderDetailDTO orderDetailDTO = new OrderDetailDTO();
        orderDetailDTO.setOrder(order);
        orderDetailDTO.setOrderDetailList(orderDetails);

        return orderDetailDTO;
    }

    @Override
    public List<Order> listByUserIdAndState(Long userId, Integer stateCode) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("state", stateCode);

        List<Order> orders = orderMapper.selectList(queryWrapper);

        return orders;
    }

    @Override
    public List<Order> listByShopIdAndState(Long shopId, Integer stateCode) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shop_id", shopId);
        queryWrapper.eq("state", stateCode);

        List<Order> orders = orderMapper.selectList(queryWrapper);

        return orders;
    }

    private String generateOrderCode(Long shopId) {
        String orderCode = RandomUtils.nextInt(1000, 10000) + "";
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("shop_id", shopId);
        queryWrapper.eq("order_code", orderCode);
        queryWrapper.lt("state", OrderStateEnum.FINISH);

        List result = orderMapper.selectList(queryWrapper);
        if (result.isEmpty()) {
            return orderCode;
        } else {
            return generateOrderCode(shopId);
        }
    }

}
